#ifndef Ex4_Graph_h
#define Ex4_Graph_h
#include <stdlib.h>
#include <string.h>
#include "ClusterInfo.h"
#include "Consts.h"

typedef struct edgeListItem {
	struct edge *edgeData;
	struct edgeListItem *next;
	struct edgeListItem *prev;
} edgeListItem;

typedef struct edgesList
{
	edgeListItem * head;
} edgesList;

typedef struct vertexQueueItem {
	struct vertex *vertexData;
	int distance;
	struct vertexQueueItem *next;
} vertexQueueItem;

typedef struct vertexQueue{
	vertexQueueItem* head;
	vertexQueueItem* last;
} vertexQueue;

typedef struct vertex {
    int id;
	char *name;
    edgesList *edges;
	int degree;
	clusterInfo* cluster;
} vertex;

typedef struct edge {
	vertex *vertex1;
	vertex *vertex2;
	double weight;
    int isDeleted;
	int id;
} edge;

typedef struct {
	vertex **vertices;
	edge **edges;
    clusterInfo** clusters;
    double totalWeight;
    int numOfClusters;
    int clustersCapacity;
	int numofVertices;
	int numOfEdges;
    int verticesCapacity;
    int edgesCapacity;
	double defaultWeigth;
} graph;

void removeEdge(graph*,int,int);
void freeList(edgesList*);
int addToList(edgesList*, edge*);
int add_vertex(graph*, char*);
int add_edge(graph *, int, int , double);
void free_graph(graph *);
void freeClusters(graph*);
int checkUniqueName(graph* ,char*);
vertex *initVertex(int, char*);
int doubleVerticesArray(graph*);
int doubleEdgesArray(graph*);
void freeVertex(vertex*);
vertex * getVertexByName(graph*,char*);
edge * isEdgeExists(vertex*,vertex*);
edge * initEdge(vertex*,vertex*,double);
int isEdgeIncludesVertex(edge*, int);
graph* initGraph(double);
void removeEdgeFromList(edgesList*,edge*);
double ** getAdjMatrix(graph*);
int addCluster(graph*, clusterInfo*);
void freeAdjMatrix(double**,int);
void freeClusters(graph*);
int enqueueVertex(vertexQueue*, vertex*, int);
vertexQueueItem* dequeueVertex(vertexQueue*);
int enqueueIfNotDiscovered(vertexQueue*, int*, vertex*, int);
void freeVertexQueue(vertexQueue*);
#endif
